/*
 * SelectClassPanel.java
 * Created on Sep 5, 2004
 *
 */
package abdn.graph.growl.editor;

import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Iterator;
import java.util.Set;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import abdn.graph.growl.RenderGrowl;
import abdn.graph.ontobrowser.ESDOntoBrowser;
import abdn.graph.ontobrowser.OBObjectNode;

import com.touchgraph.graphlayout.Node;
import com.touchgraph.graphlayout.TGPanel;
import com.touchgraph.graphlayout.graphelements.GraphEltSet;
//import abdn.taxon.property.ui.EntityPropertyPanel;

/**
 * SelectClassPanel.java
 * @author Rich
 *
 */
public class SelectClassPanel
    extends JScrollPane
    implements TreeSelectionListener {
  ClassTree classTree;
  EditorGUI ed;
  //EntityPropertyPanel propPanel;
  ClassDetailsPanel details;
  JPopupMenu popup;
  JMenuItem hideItem = new JMenuItem("Hide class");
  JMenuItem showSubItem = new JMenuItem("Show subclasses");
  JMenuItem showAllItem = new JMenuItem("Show all classes");

  OBObjectNode currentNode;

  public SelectClassPanel(final EditorGUI ed, final ClassDetailsPanel details) {
    this.ed = ed;
    this.details = details;
    setClasses(null);
  }

  /*public SelectClassPanel(final EditorGUI ed, EntityPropertyPanel details) {
    this.ed = ed;
    this.propPanel = details;
    //this.details = details;
    setClasses(null);
  }*/


  public void setClasses(Set classes) {
    classTree = new ClassTree(classes, false);
    classTree.addTreeSelectionListener(this);
    classTree.addMouseListener(new MouseAdapter() {
      public void mouseReleased(MouseEvent e) {
        TreePath path = classTree.getPathForLocation(e.getX(), e.getY());
        if (e.getModifiers() == MouseEvent.BUTTON3_MASK) {
          if (path != null) {
            classTree.setSelectionPath(path);
            OBObjectNode node = classTree.getSelection();
            if (node != null) {
              getPopup(node).show(e.getComponent(), e.getX(), e.getY());
            }
          }
        }
        else if (e.getModifiers() == MouseEvent.BUTTON1_MASK && path == null) {
          classTree.setSelectionPath(null);
        }
      }
    });
    setViewportView(classTree);
    //details.setClassNode(null);
  }

  /*public void setPropertyPanel( EntityPropertyPanel p ) {
    this.propPanel = p;
  }*/

  private JPopupMenu getPopup(OBObjectNode node) {
    if (popup == null) {
      popup = new JPopupMenu();
      hideItem.addActionListener(hideClassAction);
      showSubItem.addActionListener(showSubClassesAction);
      showAllItem.addActionListener(showAllAction);
      popup.add(hideItem);
      popup.add(showSubItem);
      popup.add(showAllItem);
    }
    if (node.isHiden) {
      hideItem.setText("Show class");
    }
    else {
      hideItem.setText("Hide class");
    }
    currentNode = node;
    return popup;
  }

  private ActionListener hideClassAction = new ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      TGPanel tgPanel = ed.getTgPanel();
      if (currentNode.isHiden) {
        currentNode.isHiden = false;
        currentNode.markedForRemoval = false;
        tgPanel.setSelect(currentNode);
        positionTo(currentNode);
      }
      else {
        tgPanel.setSelect(null);
        currentNode.isHiden = true;
        currentNode.markedForRemoval = true;
      }
      refreshGraph();
    }
  };

  private ActionListener showSubClassesAction = new ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      TGPanel tgPanel = ed.getTgPanel();
      Set classes = ed.esdOntoBrowser.getObjectNodes(RenderGrowl.OBJ_CLASS);
      Set subCls = EditorGUI.getAllSubClasses(currentNode);
      subCls.add(currentNode);
      for (Iterator i = classes.iterator(); i.hasNext(); ) {
        Node n = (Node) i.next();
        if (subCls.contains(n)) {
          n.isHiden = false;
          n.markedForRemoval = false;
        }
        else {
          n.isHiden = true;
          n.markedForRemoval = true;
        }
      }
      tgPanel.setSelect(currentNode);
      positionTo(currentNode);
      classTree.repaint();
      refreshGraph();
    }
  };

  private ActionListener showAllAction = new ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      TGPanel tgPanel = ed.getTgPanel();
      GraphEltSet eltSet = tgPanel.getCompleteEltSet();
      for (Iterator i = eltSet.getNodes().iterator(); i.hasNext(); ) {
        Node n = (Node) i.next();
        n.isHiden = false;
        n.markedForRemoval = false;
      }
      classTree.repaint();
      refreshGraph();
    }
  };

  private void refreshGraph() {
    TGPanel tgPanel = ed.getTgPanel();
    tgPanel.getLocalityUtils().removeMarkedNodes();
    tgPanel.fireResetEvent();
    tgPanel.resetDamper();
    tgPanel.layoutOnce();
  }

  public void positionTo(OBObjectNode node) {
    if (classTree != null && node != null &&
        node.objectCategory == RenderGrowl.OBJ_CLASS) {
      classTree.positionTo(node);
      //propPanel.displayProperty(node);
      details.setClassNode(node);
    }
  }

  public OBObjectNode getSelection() {
    return (classTree == null) ? null : classTree.getSelection();
  }

  /* (non-Javadoc)
   * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
   */
  public void valueChanged(TreeSelectionEvent e) {
    OBObjectNode node = classTree.getSelection();
    ESDOntoBrowser ob = ed.esdOntoBrowser;
    if (node != null && !node.isHiden) {
      if (node != ob.getTGPanel().getSelect()) {
        TGPanel tgPanel = ob.getTGPanel();
        tgPanel.setLocale(node, ob.localityScroll.getRadius());
        ob.setSelect(node);
        tgPanel.fireResetEvent();
        ob.hvScroll.slowScrollToCenter(node);
        if (!tgPanel.getVisibleLocality().contains(node)) {
          tgPanel.layoutOnce();
        }
        //propPanel.displayProperty(node);
        positionTo(node);
        classTree.repaint();
        refreshGraph();
      }
    } else {
      ob.setSelect(null);
      //details.setClassNode(null);
    }
  }

}
